package com.zifan.yygh.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zifan.common.result.ResultCodeEnum;
import com.zifan.yygh.cilent.DictFeignClient;
import com.zifan.yygh.enums.DictEnum;
import com.zifan.yygh.exception.YyghException;
import com.zifan.yygh.model.hosp.Hospital;
import com.zifan.yygh.model.hosp.HospitalSet;
import com.zifan.yygh.repository.HospitalRepository;
import com.zifan.yygh.service.HospitalService;
import com.zifan.yygh.service.HospitalSetService;
import com.zifan.yygh.utils.MD5;
import com.zifan.yygh.vo.hosp.HospitalQueryVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author Zifan
 * @date 2021年09月26日14:59
 */
@Service
public class HospitalServiceImpl implements HospitalService {
    private static final Logger log = LoggerFactory.getLogger(HospitalServiceImpl.class);

    @Autowired
    private HospitalRepository repository;

    @Autowired
    private HospitalSetService setService;

    @Autowired
    private DictFeignClient dictFeignClient;


    /**
     * 保存医院数据
     */
    @Override
    public void saveHospital(Map<String, Object> paramsMap) {
        //传输过程中“+”转换为了“ ”，因此我们要转换回来
        String logoDataString = (String) paramsMap.get("logoData");
        if (!StringUtils.isEmpty(logoDataString)) {
            String logoData = logoDataString.replaceAll(" ", "+");
            paramsMap.put("logoData", logoData);
        }

        Hospital hospital = getHospital(paramsMap);


        //查询数据库
        QueryWrapper<HospitalSet> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .select(HospitalSet::getSignKey)
                .eq(HospitalSet::getHoscode, hospital.getHoscode());
        HospitalSet hospitalSet = setService.getOne(queryWrapper);

        checkSign(paramsMap, hospitalSet);

        //1判读是否存在相同的数据
        Hospital targetHosp = repository.getHospitalByHoscode(hospital.getHoscode());

        //2存在就修改，不存在就新增
        if (ObjectUtil.isEmpty(targetHosp)) {
            //空，添加

            //状态 0：未上线 1：已上线
            hospital.setStatus(0);
            hospital.setUpdateTime(new Date());
            hospital.setCreateTime(new Date());
            hospital.setIsDeleted(0);

            //完成创建
            repository.save(hospital);

        } else {
            //非空，修改

            //这些数据前台不会上送，需要我们手动设置
            hospital.setStatus(targetHosp.getStatus());
            hospital.setUpdateTime(new Date());
            hospital.setCreateTime(targetHosp.getCreateTime());
            hospital.setIsDeleted(targetHosp.getIsDeleted());
            hospital.setId(targetHosp.getId());

            //完成修改
            repository.save(hospital);

        }

    }

    /**
     * 查询医院信息
     */
    @Override
    public Hospital showHospital(Map<String, Object> paramsMap) {
        //转换成对象
        Hospital hospital = getHospital(paramsMap);

        //查询数据库
        QueryWrapper<HospitalSet> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .select(HospitalSet::getSignKey)
                .eq(HospitalSet::getHoscode, hospital.getHoscode());
        HospitalSet hospitalSet = setService.getOne(queryWrapper);

        //验证
        checkSign(paramsMap, hospitalSet);

        //获取数据
        return repository.getHospitalByHoscode(hospital.getHoscode());
    }

    /**
     * 条件，分页，查询医院信息
     */
    @Override
    public Page<Hospital> selectPage(Integer page, Integer limit, HospitalQueryVo hospitalQueryVo) {
        //考虑封装一下，这里先这样写

        //转换VO
        Hospital hospital = new Hospital();
        BeanUtils.copyProperties(hospitalQueryVo, hospital);

        //封装查询条件
        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
                .withIgnoreCase(false);
        Example<Hospital> example = Example.of(hospital, exampleMatcher);

        //封装分页信息
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = PageRequest.of(page - 1, limit, sort);

        Page<Hospital> resPage = repository.findAll(example, pageRequest);
        //远程调用，需要封装医院等级，完整地址（省市区）
        for (Hospital h : resPage.getContent()) {
            packHospitalDetails(h);
        }

        return resPage;
    }

    /**
     * 更新状态，上线或者下线
     */
    @Override
    public void updateStatus(String id, Integer status) {
        if (status == 1 || status == 0) {
            Optional<Hospital> byId = repository.findById(id);
            if (ObjectUtil.isNull(byId)) {
                throw new YyghException(ResultCodeEnum.FAIL);
            }
            Hospital hospital = byId.get();
            hospital.setUpdateTime(new Date());
            hospital.setStatus(status);
            repository.save(hospital);
        } else {
            throw new YyghException(ResultCodeEnum.PARAM_ERROR);
        }
    }

    /**
     * 获取医院详情信息，并对返回结果进行封装
     */
    @Override
    public Map<String, Object> show(String id) {
        Map<String, Object> resMap = new HashMap<>();
        Hospital hospital = repository.findById(id).get();
        //远程调用，封装一些医院等级，省市区信息
        this.packHospitalDetails(hospital);
        resMap.put("hospital", hospital);
        //排班规则
        resMap.put("bookingRule", hospital.getBookingRule());
        //避免重复返回
        hospital.setBookingRule(null);
        return resMap;
    }

    /**
     *获取医院名称
     */
    @Override
    public String getHospName(String hoscode) {
        Hospital hospital = repository.getHospitalByHoscode(hoscode);
        if (ObjectUtil.isNotNull(hospital)) {
            return hospital.getHosname();
        }
        return "";
    }

    /**
     * 根据医院名称获取医院列表
     */
    @Override
    public List<Hospital> findByHosname(String hosname) {
        return repository.findHospitalByHosnameLike(hosname);
    }

    private Hospital getHospital(Map<String, Object> paramsMap) {
        //把paramsMap转化为对象，使用json序列化的方式
        String s = JSON.toJSONString(paramsMap);
        return JSON.parseObject(s, Hospital.class);
    }

    private void checkSign(Map<String, Object> paramsMap, HospitalSet hospitalSet) {
        //校验sign字段是否一致
        String sign = (String) paramsMap.get("sign");
        //加密后判断是否一致
        if (!StrUtil.equals(sign, MD5.encrypt(hospitalSet.getSignKey()))) {
            //不一致
            throw new YyghException(ResultCodeEnum.SIGN_ERROR);
        }
    }

    /**
     * 远程调用，封装等级信息，获取省市区信息
     * @param hospital
     */
    private void packHospitalDetails(Hospital hospital) {
        //远程调用，获取医院等级
        String hospitalGrade = dictFeignClient.getName(DictEnum.HOSTYPE.getDictCode(), hospital.getHostype());
        //远程调用，获取省市区
        String provinceString = dictFeignClient.getName(hospital.getProvinceCode());
        String cityString = dictFeignClient.getName(hospital.getCityCode());
        String districtString = dictFeignClient.getName(hospital.getDistrictCode());
        //封装数据
        hospital.getParam().put("hostypeString", hospitalGrade);
        hospital.getParam().put("fullAddress", provinceString + cityString + districtString + hospital.getAddress());
    }
}
